<script lang="ts">
    import { onMount } from "svelte";
    import type { ColumnProps } from "./Table";
    import { useTableContext } from "./Table.svelte";
    import { Checkbox } from "../Checkbox";
    import Icon from "../Common/Icons/Icon.svelte";
    import { Popover } from "../Popover";
    import { useStyle } from "../utils/useStyle";
    import dayjs from "dayjs";

    const props = $props();
    let cell: any;
    const col: ColumnProps = props.column;
    const colIndex: number = props.colIndex;
    const ctx: any = useTableContext();
    onMount(() => {
        setTimeout(() => {
            updateCellStyle();
        });
    });

    const align = col.align || "left";
    const cellClassList = $derived({
        "cm-table-head-col": props.type === "th",
        [`cm-table-cell-align-${align}`]: align,
        "cm-table-cell-fixed-left-last": col.fixedLeftLast && props.showFixedLeft,
        "cm-table-cell-fixed-right-first": col.fixedRightFirst && props.showFixedRight,
    });

    $effect(() => {
        col.width;
        col._;
        props.showFixedRight;
        props.showFixedLeft;
        updateCellStyle();
    });

    const updateCellStyle = () => {
        if (col.fixed && cell && !props.placeholder) {
            if (col.fixed === "left") {
                cell.style.position = "static";
                const parent = cell.closest(".cm-table");
                if (parent) {
                    const head = parent.querySelector("thead");
                    let left = 0;
                    for (let i = 1; i <= colIndex; i++) {
                        const th = head.querySelector("th:nth-child(" + i + ")");
                        if (th) {
                            left += th.getBoundingClientRect().width;
                        }
                    }

                    cell.style.position = "sticky";
                    cell.style.left = left + "px";
                    cell.style.zIndex = props.type === "th" ? 3 : 1;
                    cell.classList.add("cm-table-cell-fixed-left");
                    if (col.fixedLeftLast && props.showFixedLeft) {
                        cell.classList.add("cm-table-cell-fixed-left-last");
                    }
                }
            }
            if (col.fixed === "right") {
                const parent = cell.closest(".cm-table");
                if (parent) {
                    const head = parent.querySelector("thead");
                    const length = head.querySelectorAll("th").length;

                    let w = 0;
                    for (let i = colIndex + 2; i <= length; i++) {
                        const th = head.querySelector("th:nth-child(" + i + ")");
                        w += th.getBoundingClientRect().width;
                    }
                    cell.style.position = "sticky";
                    cell.style.right = w + "px";
                    cell.style.zIndex = props.type === "th" ? 3 : 1;
                    cell.classList.add("cm-table-cell-fixed-right");
                    if (col.fixedRightFirst && props.showFixedRight) {
                        cell.classList.add("cm-table-cell-fixed-right-first");
                    }
                }
            }
        }
    };

    // 选择框选择事件
    const onRowChecked = (checked: boolean) => {
        ctx && ctx.onRowChecked(props.data, checked);
    };

    // 头部选择框选择事件
    const onHeadChecked = (checked: boolean) => {
        ctx && ctx.onHeadChecked(checked);
    };

    // 点击排序
    const onSort = (sortType: string) => {
        ctx && ctx.onSort(col, sortType);
    };

    // 点击树型展开图标
    const onShowChildren = () => {
        ctx && ctx.onShowChildren(props.data);
    };

    // 展开
    const onExpand = () => {
        ctx && ctx.onExpand(col, props.data);
    };

    // onDragStart
    const onDragStart = (e: any) => {
        ctx && ctx.onDragStart(col, e);
    };
</script>

{#snippet text()}
    {#if props.type === "td"}
        {#if props.summary}
            {props.data[props.column.name]}
        {:else if props.column.type === "index"}
            {props.index + 1}
        {:else if props.column.type === "date"}
            {dayjs(props.data[props.column.name]).format("YYYY-MM-DD")}
        {:else if props.column.type === "datetime"}
            {dayjs(props.data[props.column.name]).format("YYYY-MM-DD HH:mm:ss")}
        {:else if props.column.type === "enum"}
            {props.column.enum?.[props.data[props.column.name]]}
        {:else if props.column.type === "checkbox"}
            <Checkbox disabled={props.data._disabled} checked={props.data._checked} onchange={onRowChecked} />
        {:else if props.data._type === "expandChildren"}
            {@render props.data.render?.(props.data.data)}
        {:else if props.column.type === "expand"}
            <Icon icon="chevronRight" class={`cm-table-expand ${props.data._expand ? "cm-table-expand-open" : ""}`} onclick={onExpand} />
        {:else if props.column.render && typeof props.column.render === "function"}
            {@render props.column.render({
                value: props.data[props.column.name],
                column: props.column,
                record: props.data,
                index: props.index,
            })}
        {:else}
            {props.data[props.column.name]}
        {/if}
    {:else if props.column.type === "checkbox"}
        <Checkbox checked={props.checkedAll} onchange={onHeadChecked} />
    {:else if typeof props.column.title === "function"}
        {@render props.column.title()}
    {:else}
        {props.column.title}
    {/if}
{/snippet}

{#if props.type === "th"}
    <th bind:this={cell} class={cellClassList} colSpan={props.colSpan} rowSpan={props.rowSpan} data-index={props.colIndex}>
        <div class="cm-table-cell">
            {@render text()}
            {#if col.sort}
                <span class="cm-table-sort">
                    <Icon icon="chevronUp" class={col.sortType === "asc" ? "cm-table-sort-active" : ""} onclick={onSort.bind(null, "asc")} />
                    <Icon icon="chevronDown" class={col.sortType === "desc" ? "cm-table-sort-active" : ""} onclick={onSort.bind(null, "desc")} />
                </span>
            {/if}
            {#if col.resize && col.width && ctx && ctx.border}
                <!-- svelte-ignore a11y_no_static_element_interactions -->
                <span class="cm-table-resize" onmousedown={onDragStart}></span>
            {/if}
        </div>
    </th>
{/if}
{#if props.type === "td"}
    <td bind:this={cell} class={cellClassList} colSpan={props.colSpan} rowSpan={props.rowSpan}>
        <div class="cm-table-cell">
            {#if col.tree}
                <span class="cm-table-tree-level" style={`padding-left: ${props.data._level * 16}px`}></span>
                {#if props.data.children && props.data.children.length}
                    {#if props.data._showChildren}
                        <Icon icon="minusSquare" class="cm-table-tree-icon" onclick={onShowChildren} />
                    {:else}
                        <Icon icon="plusSquare" class="cm-table-tree-icon" onclick={onShowChildren} />
                    {/if}
                {:else}
                    <span class="cm-table-tree-icon-empty"></span>
                {/if}
            {/if}
            {#if col.ellipsis || col.tooltip}
                {#if col.tooltip}
                    {@const tooltipProps = typeof col.tooltip === "object" ? col.tooltip : {}}
                    <Popover arrow style="max-width: 200px" {...tooltipProps} class="cm-table-cell-tooltip">
                        {#snippet content()}
                            <div>{@render text()}</div>
                        {/snippet}
                        <span class="cm-table-cell-tooltip-content">{@render text()}</span>
                    </Popover>
                {:else}
                    <span class="cm-table-cell-ellipsis">{@render text()}</span>
                {/if}
            {:else}
                {@render text()}
            {/if}
        </div>
    </td>
{/if}
